﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Heightmap_Editor.Menu.Screens
{
    class ExportScreen : MenuScreen
    {
        private volatile MenuProgressBar _progressBar;
        private Texture2D _destination;

        private MenuImage preview;
        private MenuEntry save;

        public ExportScreen()
            : base("Save Maps")
        {
            MenuEntry saveHeightmap = new MenuEntry("Generate Heightmap...");
            _progressBar = new MenuProgressBar(0f);
            save = new MenuEntry("Save Map...");

            saveHeightmap.Selected += saveHeightmap_Selected;
            save.Selected += save_Selected;

            MenuEntries.Add(saveHeightmap);
            MenuWidgets.Add(_progressBar);
        }

        void save_Selected(object sender, GameStateManagement.PlayerIndexEventArgs e)
        {
            var sfd = new SaveFileDialog { Title = "Save Heightmap", Filter = "JPEG-Files|*.jpg|PNG-Files|*.png" };

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                var file = new FileStream(sfd.FileName, FileMode.Create, FileAccess.Write);
                if (sfd.FilterIndex == 0)
                    _destination.SaveAsJpeg(file, _destination.Width, _destination.Height);
                else if (sfd.FilterIndex == 1)
                    _destination.SaveAsPng(file, _destination.Width, _destination.Height);
                file.Close();
            }
        }

        void saveHeightmap_Selected(object sender, GameStateManagement.PlayerIndexEventArgs e)
        {
            Thread thread = new Thread(SaveHeightmapThread);
            thread.Start();
        }

        void SaveHeightmapThread()
        {
            _destination = new Texture2D(HeightmapEditor.Instance.GraphicsDevice,
                                      HeightmapEditor.Instance.TerrainWidth * 64,
                                      HeightmapEditor.Instance.TerrainHeight * 64);

            var texture = new Color[_destination.Width * _destination.Height];

            int width = HeightmapEditor.Instance.TerrainWidth;
            int height = HeightmapEditor.Instance.TerrainHeight;
            int runs = width * height * 64 * 64;

            for (int cx = 0; cx < width; cx++)
            {
                for (int cy = 0; cy < height; cy++)
                {
                    for (int x = 0; x < 64; x++)
                    {
                        for (int y = 0; y < 64; y++)
                        {
                            int pixelColor = ((int)(HeightmapEditor.Instance.VertexChunks[cx + cy * width][x + y * 65].Position.Y * 5) + 128);

                            if (pixelColor < 0) pixelColor = 0;
                            if (pixelColor > 255) pixelColor = 255;

                            texture[(cx * 64 + x) + (cy * 64 + y) * _destination.Width] =
                                Color.FromNonPremultiplied(pixelColor, pixelColor, pixelColor, 255);

                            _progressBar.Progress = (((cx * 64 + x) + (cy * 64 + y) * _destination.Width + 1) / (float)runs) * 100;
                        }
                    }
                }
            }
            _destination.SetData(texture);

            if (!MenuEntries.Contains(save))
            {
                MenuEntries.Add(save);

                preview = new MenuImage(_destination);
                MenuWidgets.Add(preview);
            }
            preview.Texture = _destination;
        }
    }
}
